home *** CD-ROM | disk | FTP | other *** search
- /*
- ** termTranslate.c
- **
- ** Character translation support routines
- **
- ** Copyright © 1990-1995 by Olaf `Olsen' Barthel
- ** All Rights Reserved
- */
-
- #include "termGlobal.h"
-
- /* Translation chunk header types. */
-
- enum { TYPE_NONE, TYPE_SEND, TYPE_RECEIVE };
-
- /* Master translation table entry types. */
-
- enum { TRANSLATION_VERBATIM, TRANSLATION_IGNORE, TRANSLATION_OTHER };
-
- /* Symbolic names for character codes. */
-
- STATIC struct { STRPTR Name; UBYTE Value; } CodeTab[44] =
- {
- { "NUL", 0 },
- { "SOH", 1 },
- { "STX", 2 },
- { "ETX", 3 },
- { "EOT", 4 },
- { "ENQ", 5 },
- { "ACK", 6 },
- { "BEL", 7 },
- { "BS", 8 },
- { "HT", 9 },
- { "LF", 10 },
- { "VT", 11 },
- { "FF", 12 },
- { "CR", 13 },
- { "SO", 14 },
- { "SI", 15 },
- { "DLE", 16 },
- { "DC1", 17 },
- { "DC2", 18 },
- { "DC3", 19 },
- { "DC4", 20 },
- { "NAK", 21 },
- { "SYN", 22 },
- { "ETB", 23 },
- { "CAN", 24 },
- { "EM", 25 },
- { "SUB", 26 },
- { "ESC", 27 },
- { "FS", 28 },
- { "GS", 29 },
- { "RS", 30 },
- { "US", 31 },
- { "SP", 32 },
- { "DEL", 127 },
- { "SS2", 142 },
- { "SS3", 143 },
- { "DCS", 144 },
- { "CSI", 155 },
- { "ST", 156 },
- { "OSC", 157 },
- { "PM", 158 },
- { "APC", 159 },
- { "NBS", 160 },
- { "SHY", 173 }
- };
-
- /* TranslateSetup():
- *
- * Set up for buffer translation.
- */
-
- VOID __regargs
- TranslateSetup(struct TranslationHandle *Handle,STRPTR SourceBuffer,LONG SourceLen,STRPTR DestinationBuffer,LONG DestinationLen,struct TranslationEntry **Table)
- {
- Handle -> LocalBuffer = NULL;
- Handle -> LocalLen = 0;
-
- Handle -> SourceBuffer = SourceBuffer;
- Handle -> SourceLen = SourceLen;
-
- Handle -> DestinationBuffer = DestinationBuffer;
- Handle -> DestinationLen = DestinationLen;
-
- Handle -> Table = Table;
- }
-
- /* TranslateBuffer(struct TranslationHandle *Handle):
- *
- * Translate buffer contents according to
- * translation table contents.
- */
-
- LONG __regargs
- TranslateBuffer(struct TranslationHandle *Handle)
- {
- register STRPTR Data = Handle -> DestinationBuffer;
- register LONG BytesWritten = 0;
- register struct TranslationEntry *Entry;
-
- /* Are we to return any translated data? */
-
- while(Handle -> LocalLen && BytesWritten < Handle -> DestinationLen)
- {
- /* Decrement number of bytes in buffer. */
-
- Handle -> LocalLen--;
-
- /* Return next character. */
-
- *Data++ = *Handle -> LocalBuffer++;
-
- /* Add another byte. */
-
- BytesWritten++;
- }
-
- /* Loop until done. */
-
- while(Handle -> SourceLen && BytesWritten < Handle -> DestinationLen)
- {
- /* Another byte eaten. */
-
- Handle -> SourceLen--;
-
- /* Get table entry. */
-
- if(Entry = Handle -> Table[*Handle -> SourceBuffer++])
- {
- /* Copy to local data area. */
-
- Handle -> LocalBuffer = Entry -> String;
- Handle -> LocalLen = Entry -> Len;
-
- /* Translate the data. */
-
- while(Handle -> LocalLen && BytesWritten < Handle -> DestinationLen)
- {
- /* Decrement number of bytes in buffer. */
-
- Handle -> LocalLen--;
-
- /* Return next character. */
-
- *Data++ = *Handle -> LocalBuffer++;
-
- /* Add another byte. */
-
- BytesWritten++;
- }
- }
- }
-
- return(BytesWritten);
- }
-
- /* NameToCode(STRPTR Name):
- *
- * Translate a symbolic character code name of numeral.
- */
-
- UBYTE __regargs
- NameToCode(STRPTR Name)
- {
- WORD i;
-
- for(i = 0 ; i < 44 ; i++)
- {
- if(!Stricmp(CodeTab[i] . Name,Name))
- return(CodeTab[i] . Value);
- }
-
- return((UBYTE)Atol(Name));
- }
-
- /* CodeToName(UBYTE Code):
- *
- * Translate a character code into a symbolic
- * name or numeral.
- */
-
- STRPTR __regargs
- CodeToName(UBYTE Code)
- {
- STATIC UBYTE Name[6];
-
- WORD i;
-
- for(i = 0 ; i < 44 ; i++)
- {
- if(CodeTab[i] . Value == Code)
- return(CodeTab[i] . Name);
- }
-
- SPrintf(Name,"%03ld",Code);
-
- return(Name);
- }
-
- /* FreeTranslationTable(struct TranslationEntry **Table):
- *
- * Free a character translation table.
- */
-
- VOID __regargs
- FreeTranslationTable(struct TranslationEntry **Table)
- {
- WORD i;
-
- for(i = 0 ; i < 256 ; i++)
- {
- if(Table[i])
- FreeTranslationEntry(Table[i]);
- }
-
- FreeVecPooled(Table);
- }
-
- /* AllocTranslationTable():
- *
- * Allocate a character translation table.
- */
-
- struct TranslationEntry **
- AllocTranslationTable()
- {
- return((struct TranslationEntry **)AllocVecPooled(sizeof(struct TranslationEntry *) * 256,MEMF_ANY|MEMF_CLEAR));
- }
-
- /* FreeTranslationEntry(struct TranslationEntry *Entry):
- *
- * Free a character translation table entry.
- */
-
- VOID __regargs
- FreeTranslationEntry(struct TranslationEntry *Entry)
- {
- FreeVecPooled(Entry);
- }
-
- /* TranslateString(STRPTR From,STRPTR To):
- *
- * Translate a string to contain control codes
- * into a string to contain the real codes.
- */
-
- LONG __regargs
- TranslateString(STRPTR From,STRPTR To)
- {
- BYTE GotControl = FALSE,
- GotEscape = FALSE;
-
- LONG Len = strlen(From),
- Count = 0,
- i;
-
- for(i = 0 ; i < Len ; i++)
- {
- if(!GotControl && !GotEscape)
- {
- if(From[i] == '\\')
- {
- GotControl = TRUE;
-
- continue;
- }
-
- if(From[i] == '^')
- {
- GotEscape = TRUE;
-
- continue;
- }
-
- To[Count++] = From[i];
- }
- else
- {
- if(GotEscape)
- {
- if(ToUpper(From[i]) >= 'A' && ToUpper(From[i]) <= '_')
- To[Count++] = ToUpper(From[i]) - '@';
- else
- To[Count++] = From[i];
-
- GotEscape = FALSE;
- }
- else
- {
- if(GotControl)
- {
- switch(ToUpper(From[i]))
- {
- /* These macro commands are plainly
- * ignored.
- */
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
-
- break;
-
- /* These are macro commands and
- * not supported.
- */
-
- case 'A':
- case 'C':
- case 'D':
- case 'G':
- case 'H':
- case 'I':
- case 'P':
- case 'U':
- case 'X':
-
- To[Count++] = '\\';
- To[Count++] = From[i];
- break;
-
- /* Translate code. */
-
- case '*':
-
- i++;
-
- while(i < Len && From[i] == ' ')
- i++;
-
- if(i < Len)
- {
- UBYTE DummyBuffer[5],j = 0,Char;
-
- if(From[i] >= '0' && From[i] <= '9')
- {
- while(j < 3 && i < Len)
- {
- Char = From[i++];
-
- if(Char >= '0' && Char <= '9')
- DummyBuffer[j++] = Char;
- else
- {
- i--;
-
- break;
- }
- }
- }
- else
- {
- while(j < 4 && i < Len)
- {
- Char = ToLower(From[i++]);
-
- if((Char >= '0' && Char <= '9') || (Char >= 'a' && Char <= 'z'))
- DummyBuffer[j++] = Char;
- else
- {
- i--;
-
- break;
- }
- }
- }
-
- DummyBuffer[j] = 0;
-
- To[Count++] = NameToCode(DummyBuffer);
- }
-
- i--;
-
- break;
-
- /* This is a backspace. */
-
- case 'B':
-
- To[Count++] = '\b';
- break;
-
- /* This is a form feed. */
-
- case 'F':
-
- To[Count++] = '\f';
- break;
-
- /* This is a line feed. */
-
- case 'N':
-
- To[Count++] = '\n';
- break;
-
- /* This is a carriage return. */
-
- case 'R':
-
- To[Count++] = '\r';
- break;
-
- /* This is a tab. */
-
- case 'T':
-
- To[Count++] = '\t';
- break;
-
- /* Produce the escape character. */
-
- case 'E':
-
- To[Count++] = ESC;
- break;
-
- /* Stuff the character into the buffer. */
-
- default:
-
- To[Count++] = From[i];
- break;
- }
-
- GotControl = FALSE;
- }
- }
- }
- }
-
- return(Count);
- }
-
- /* AllocTranslationEntry(STRPTR String):
- *
- * Allocate a character translation table entry.
- */
-
- struct TranslationEntry * __regargs
- AllocTranslationEntry(STRPTR String)
- {
- LONG Count = TranslateString(String,SharedBuffer);
-
- if(Count > 0)
- {
- struct TranslationEntry *Entry;
- UBYTE Type;
-
- if(Count > 1)
- {
- Type = TRANSLATE_STRING;
-
- if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry) + Count + 1,MEMF_ANY|MEMF_CLEAR))
- {
- Entry -> String = (STRPTR)(Entry + 1);
-
- memcpy(Entry -> String,SharedBuffer,Count);
- }
- }
- else
- {
- Type = TRANSLATE_SINGLE;
-
- if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
- {
- Entry -> String = &Entry -> Extra;
- Entry -> Extra = SharedBuffer[0];
- }
- }
-
- if(Entry)
- {
- Entry -> Type = Type;
- Entry -> Len = Count;
-
- return(Entry);
- }
- }
-
- return(NULL);
- }
-
- /* FillTranslationTable(struct TranslationEntry **Table):
- *
- * Fill the translation table with defaults.
- */
-
- BYTE __regargs
- FillTranslationTable(struct TranslationEntry **Table)
- {
- BYTE Success = TRUE;
- WORD i;
-
- for(i = 0 ; Success && i < 256 ; i++)
- {
- if(Table[i] = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
- {
- Table[i] -> Type = TRANSLATE_SINGLE;
- Table[i] -> String = &Table[i] -> Extra;
- Table[i] -> Extra = i;
- Table[i] -> Len = 1;
- }
- else
- Success = FALSE;
- }
-
- if(!Success)
- {
- for(i = 0 ; i < 256 ; i++)
- {
- if(Table[i])
- {
- FreeVecPooled(Table[i]);
-
- Table[i] = NULL;
- }
- }
- }
-
- return(Success);
- }
-
- /* IsStandardTable(struct TranslationEntry **Table):
- *
- * Checks a translation table to see if it contains
- * standard data.
- */
-
- BYTE __regargs
- IsStandardTable(struct TranslationEntry **Table)
- {
- WORD i;
-
- for(i = 0 ; i < 256 ; i++)
- {
- if(Table[i])
- {
- if(Table[i] -> Type != TRANSLATE_SINGLE || Table[i] -> Len != 1 || Table[i] -> String[0] != i)
- return(FALSE);
- }
- else
- return(FALSE);
- }
-
- return(TRUE);
- }
-
- /* TranslateBack(STRPTR From,LONG Len,STRPTR To):
- *
- * Translate a precompiled translation string
- * back.
- */
-
- VOID __regargs
- TranslateBack(STRPTR From,LONG Len,STRPTR To)
- {
- STATIC char TypeTable[256] =
- {
- 1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 ,'b','t','n', 1 ,'f','r', 1 , 1,
- 1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 1 , 1 , 1 ,'e', 1 , 1 , 1 , 1,
- 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
- 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
- 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
- 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 ,'\\',2 , 2 , 2,
- 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
- 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 0,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 ,0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 ,0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
- 0 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 0 , 2 , 2,
- 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
- 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
- 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
- 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
- 2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2
- };
-
- STRPTR Buffer;
- LONG i,j,BufLen;
-
- for(i = j = 0 ; i < Len ; i++)
- {
- switch(TypeTable[From[i]])
- {
- case 0: To[j++] = '\\';
- To[j++] = '*';
-
- Buffer = CodeToName(From[i]);
-
- BufLen = strlen(Buffer);
-
- memcpy(&To[j],Buffer,BufLen);
-
- j += BufLen;
-
- break;
-
- case 1: To[j++] = '^';
- To[j++] = From[i] + '@';
- break;
-
- case 2: To[j++] = From[i];
- break;
-
- default:To[j++] = '\\';
- To[j++] = TypeTable[From[i]];
- break;
- }
- }
-
- To[j] = 0;
- }
-
- /* SaveTranslationTables():
- *
- * Save a character translation table to a file.
- */
-
- BYTE __regargs
- SaveTranslationTables(STRPTR Name,struct TranslationEntry **SendTable,struct TranslationEntry **ReceiveTable)
- {
- BYTE Success = FALSE,
- DoIt = FALSE;
- WORD i;
- LONG Error = 0;
-
- for(i = 0 ; !DoIt && i < 256 ; i++)
- {
- if(SendTable[i] || ReceiveTable[i])
- DoIt = TRUE;
- }
-
- if(DoIt)
- {
- struct IFFHandle *Handle;
- UBYTE MasterTable[256];
-
- for(i = 0 ; i < 256 ; i++)
- {
- if(SendTable[i])
- {
- if(SendTable[i] -> Type == TRANSLATE_SINGLE && SendTable[i] -> Len == 1 && SendTable[i] -> String[0] == i)
- MasterTable[i] = TRANSLATION_VERBATIM;
- else
- MasterTable[i] = TRANSLATION_OTHER;
- }
- else
- MasterTable[i] = TRANSLATION_IGNORE;
-
- if(ReceiveTable[i])
- {
- if(ReceiveTable[i] -> Type == TRANSLATE_SINGLE && ReceiveTable[i] -> Len == 1 && ReceiveTable[i] -> String[0] == i)
- MasterTable[i] |= TRANSLATION_VERBATIM << 4;
- else
- MasterTable[i] |= TRANSLATION_OTHER << 4;
- }
- else
- MasterTable[i] |= TRANSLATION_IGNORE << 4;
- }
-
- if(Handle = AllocIFF())
- {
- if(Handle -> iff_Stream = Open(Name,MODE_NEWFILE))
- {
- InitIFFasDOS(Handle);
-
- if(!(Error = OpenIFF(Handle,IFFF_WRITE)))
- {
- if(!(Error = PushChunk(Handle,ID_TERM,ID_CAT,IFFSIZE_UNKNOWN)))
- {
- if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
- {
- if(!(Error = PushChunk(Handle,0,ID_VERS,IFFSIZE_UNKNOWN)))
- {
- struct TermInfo TermInfo;
-
- TermInfo . Version = CONFIG_FILE_VERSION;
- TermInfo . Revision = CONFIG_FILE_REVISION;
-
- if(WriteChunkRecords(Handle,&TermInfo,sizeof(struct TermInfo),1))
- {
- if(!(Error = PopChunk(Handle)))
- {
- if(!(Error = PushChunk(Handle,0,ID_TRNS,256)))
- {
- if(WriteChunkBytes(Handle,MasterTable,256) == 256)
- {
- if(!(Error = PopChunk(Handle)))
- {
- if(!(Error = PopChunk(Handle)))
- {
- struct TranslationHeader Header;
-
- Success = TRUE;
-
- for(i = 0 ; Success && i < 256 ; i++)
- {
- if(SendTable[i] && (MasterTable[i] & 0xF) == TRANSLATION_OTHER)
- {
- Header . Type = SendTable[i] -> Type;
- Header . Len = SendTable[i] -> Len;
- Header . Code = i;
- Header . Pad = 0;
-
- if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
- {
- if(!(Error = PushChunk(Handle,0,ID_SEND,sizeof(struct TranslationHeader))))
- {
- if(WriteChunkRecords(Handle,&Header,sizeof(struct TranslationHeader),1))
- {
- if(!(Error = PopChunk(Handle)))
- {
- if(!(Error = PushChunk(Handle,0,ID_CHRS,SendTable[i] -> Len)))
- {
- if(WriteChunkRecords(Handle,SendTable[i] -> String,SendTable[i] -> Len,1))
- {
- if(Error = PopChunk(Handle))
- Success = FALSE;
- }
- else
- {
- Error = IoErr();
-
- Success = FALSE;
- }
- }
- }
- else
- Success = FALSE;
- }
- else
- {
- Error = IoErr();
-
- Success = FALSE;
- }
- }
-
- if(Success)
- {
- if(PopChunk(Handle))
- Success = FALSE;
- }
- }
- else
- Success = FALSE;
- }
-
- if(ReceiveTable[i] && (MasterTable[i] >> 4) == TRANSLATION_OTHER)
- {
- Header . Type = ReceiveTable[i] -> Type;
- Header . Len = ReceiveTable[i] -> Len;
- Header . Code = i;
- Header . Pad = 0;
-
- if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
- {
- if(!(Error = PushChunk(Handle,0,ID_RECV,sizeof(struct TranslationHeader))))
- {
- if(WriteChunkRecords(Handle,&Header,sizeof(struct TranslationHeader),1))
- {
- if(!(Error = PopChunk(Handle)))
- {
- if(!(Error = PushChunk(Handle,0,ID_CHRS,ReceiveTable[i] -> Len)))
- {
- if(WriteChunkRecords(Handle,ReceiveTable[i] -> String,ReceiveTable[i] -> Len,1))
- {
- if(Error = PopChunk(Handle))
- Success = FALSE;
- }
- else
- {
- Error = IoErr();
-
- Success = FALSE;
- }
- }
- }
- else
- Success = FALSE;
- }
- else
- {
- Error = IoErr();
-
- Success = FALSE;
- }
- }
-
- if(Success)
- {
- if(Error = PopChunk(Handle))
- Success = FALSE;
- }
- }
- else
- Success = FALSE;
- }
- }
- }
- }
- }
- else
- Error = IoErr();
- }
- }
- }
- else
- Error = IoErr();
- }
- }
-
- if(Success)
- {
- if(PopChunk(Handle))
- Success = FALSE;
- }
- }
-
- CloseIFF(Handle);
- }
-
- Close(Handle -> iff_Stream);
-
- if(Success)
- AddProtection(Name,FIBF_EXECUTE);
- else
- DeleteFile(Name);
- }
- else
- Error = IoErr();
-
- FreeIFF(Handle);
- }
- else
- Error = ERR_NO_MEM;
- }
-
- if(Error)
- SetIoErr(Error);
-
- return(Success);
- }
-
- /* LoadTranslationTable()s:
- *
- * Load a translation table from a file.
- */
-
- BYTE __regargs
- LoadTranslationTables(STRPTR Name,struct TranslationEntry **SendTable,struct TranslationEntry **ReceiveTable)
- {
- STATIC ULONG Stops[5 * 2] =
- {
- ID_TERM, ID_VERS,
- ID_TERM, ID_TRNS,
- ID_TERM, ID_SEND,
- ID_TERM, ID_RECV,
- ID_TERM, ID_CHRS
- };
-
- struct IFFHandle *Handle;
- BYTE Success = FALSE;
- WORD i;
-
- UBYTE MasterTable[256];
- BYTE GotMasterTable = FALSE;
- LONG Error;
-
- if(Handle = AllocIFF())
- {
- if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
- {
- InitIFFasDOS(Handle);
-
- if(!(Error = OpenIFF(Handle,IFFF_READ)))
- {
- if(!(Error = StopChunks(Handle,(LONG *)Stops,5)))
- {
- struct ContextNode *Chunk;
- struct TermInfo TermInfo;
- struct TranslationHeader Header;
- BYTE LastType = TYPE_NONE;
-
- Success = TRUE;
-
- while(Success && !ParseIFF(Handle,IFFPARSE_SCAN))
- {
- Chunk = CurrentChunk(Handle);
-
- switch(Chunk -> cn_ID)
- {
- case ID_VERS:
-
- if(ReadChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
- {
- if(TermInfo . Version > CONFIG_FILE_VERSION || (TermInfo . Version == CONFIG_FILE_VERSION && TermInfo . Revision > CONFIG_FILE_REVISION))
- {
- Error = ERR_OUTDATED;
-
- Success = FALSE;
- }
- }
- else
- {
- Error = IoErr();
-
- Success = FALSE;
- }
-
- break;
-
- case ID_TRNS:
-
- if(ReadChunkBytes(Handle,MasterTable,256) == 256)
- GotMasterTable = TRUE;
- else
- {
- Error = IoErr();
-
- Success = FALSE;
- }
-
- break;
-
- case ID_SEND:
-
- if(LastType != TYPE_NONE)
- Success = FALSE;
- else
- {
- if(!ReadChunkRecords(Handle,&Header,MIN(sizeof(struct TranslationHeader),Chunk -> cn_Size),1))
- {
- Error = IoErr();
-
- Success = FALSE;
- }
- else
- LastType = TYPE_SEND;
- }
-
- break;
-
- case ID_RECV:
-
- if(LastType != TYPE_NONE)
- {
- Error = IFFERR_MANGLED;
-
- Success = FALSE;
- }
- else
- {
- if(!ReadChunkRecords(Handle,&Header,MIN(sizeof(struct TranslationHeader),Chunk -> cn_Size),1))
- {
- Success = FALSE;
-
- Error = IoErr();
- }
- else
- LastType = TYPE_RECEIVE;
- }
-
- break;
-
- case ID_CHRS:
-
- if(LastType == TYPE_NONE)
- {
- Error = IFFERR_MANGLED;
-
- Success = FALSE;
- }
- else
- {
- if(ReadChunkRecords(Handle,SharedBuffer,Header . Len,1))
- {
- struct TranslationEntry *Entry;
-
- if(Header . Type == TRANSLATE_SINGLE)
- {
- if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
- {
- Entry -> String = &Entry -> Extra;
- Entry -> Extra = SharedBuffer[0];
- }
- }
- else
- {
- if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry) + Header . Len + 1,MEMF_ANY|MEMF_CLEAR))
- {
- Entry -> String = (STRPTR)(Entry + 1);
-
- memcpy(Entry -> String,SharedBuffer,Header . Len);
- }
- }
-
- if(Entry)
- {
- Entry -> Type = Header . Type;
- Entry -> Len = Header . Len;
-
- if(LastType == TYPE_SEND)
- SendTable[Header . Code] = Entry;
- else
- ReceiveTable[Header . Code] = Entry;
-
- LastType = TYPE_NONE;
- }
- else
- {
- Error = ERR_NO_MEM;
-
- Success = FALSE;
- }
- }
- else
- {
- Error = IoErr();
-
- Success = FALSE;
- }
- }
-
- break;
- }
- }
- }
-
- CloseIFF(Handle);
- }
-
- Close(Handle -> iff_Stream);
- }
- else
- Error = IoErr();
-
- FreeIFF(Handle);
- }
- else
- Error = ERR_NO_MEM;
-
- if(Success && GotMasterTable)
- {
- struct TranslationEntry *Entry;
-
- for(i = 0 ; i < 256 ; i++)
- {
- if((MasterTable[i] & 0xF) == TRANSLATION_VERBATIM)
- {
- if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
- {
- Entry -> Type = TRANSLATE_SINGLE;
- Entry -> String = &Entry -> Extra;
- Entry -> Extra = i;
- Entry -> Len = 1;
-
- SendTable[i] = Entry;
- }
- else
- {
- Error = ERR_NO_MEM;
-
- Success = FALSE;
-
- break;
- }
- }
-
- if((MasterTable[i] >> 4) == TRANSLATION_VERBATIM)
- {
- if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
- {
- Entry -> Type = TRANSLATE_SINGLE;
- Entry -> String = &Entry -> Extra;
- Entry -> Extra = i;
- Entry -> Len = 1;
-
- ReceiveTable[i] = Entry;
- }
- else
- {
- Error = ERR_NO_MEM;
-
- Success = FALSE;
-
- break;
- }
- }
- }
- }
-
- if(!Success)
- {
- for(i = 0 ; i < 256 ; i++)
- {
- if(SendTable[i])
- {
- FreeTranslationEntry(SendTable[i]);
-
- SendTable[i] = NULL;
- }
-
- if(ReceiveTable[i])
- {
- FreeTranslationEntry(ReceiveTable[i]);
-
- ReceiveTable[i] = NULL;
- }
- }
- }
-
- if(Error)
- SetIoErr(Error);
-
- return(Success);
- }
-